home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / KEYBOARD.SWG / 0007_Keyboard Handler.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  5KB  |  226 lines

  1. {
  2. >     I need help on reading the keyboard in a specific way, I need to
  3. > read it as a whole not a key at a time. I need to do this for
  4. > the games I make, I have to ba able to hold down one key to
  5. > perform a Function and then hold down another key and scan both
  6. > keys at the same time but to perform 2 different Functions. For
  7. > instance, if I hold down the left arrow key to make a Character
  8. > run I should be able to hold down the space bar to make him
  9. > fire a gun at the same time.
  10. >     I would Really appreciate any help anyone could give me With this.
  11.  
  12. Grab this (TWOKEYS.PAS) and the next 2 messages (KEYINTR.PAS and POLL.PAS).
  13. }
  14.  
  15. Program TwoKeys;
  16.  
  17. Uses
  18.   Crt, Poll ;  { polled keyboard handler }
  19.  
  20. { ----- this Program will probably hang a debugger ----- }
  21.  
  22. Var
  23.   X, Y : Byte ;
  24.  
  25. begin
  26.   ClrScr ;
  27.   X := 40 ;
  28.   Y := 12 ;
  29.  
  30.   WriteLn( 'Hit keys A S  and  1 2 on the keypad' ) ;
  31.   WriteLn( ' -- Esc to stop' ) ;
  32.  
  33.   While not KeyTable[ EscKey ] do
  34.   begin
  35.     GotoXY( X, Y ) ;
  36.     Write( ' ' ) ;
  37.  
  38.     { poll the KeyTable }
  39.     If KeyTable[ endKey ] and ( X > 1 ) then  Dec( X ) ;
  40.     If KeyTable[ DownKey ] and ( X < 80 ) then  Inc( X ) ;
  41.     If KeyTable[ aKey ] and ( Y > 4 ) then  Dec( Y ) ;
  42.     If KeyTable[ sKey ] and ( Y < 24 ) then  Inc( Y ) ;
  43.  
  44.     GotoXY( X, Y ) ;
  45.     Write( chr( 1 ) ) ;
  46.     Delay( 10 ) ;
  47.   end ;
  48. end.
  49.  
  50.  
  51.  
  52.  
  53. Unit KeyIntr ;  { support For INT 09 routines }
  54.  
  55. Interface
  56.  
  57. Procedure CLI ; Inline( $FA ) ; { disable interrupts }
  58. Procedure STI ; Inline( $FB ) ; { enable interrupts }
  59.  
  60. { cannot be used outside an interrupt Procedure }
  61. Procedure JumpInterrupt( p : Pointer ) ;
  62. Inline(
  63.   $5B/$58/                         { POP  BX, AX   AX:BX = p }
  64.   $89/$EC/                         { MOV  SP, BP             }
  65.   $87/$46/$10/                     { XCHG AX, [BP+10H]       }
  66.   $87/$5E/$0E/                     { XCHG BX, [BP+0EH]       }
  67.   $5D/$07/$1F/$5F/$5E/             { POP  BP, ES, DS, DI, SI }
  68.   $5A/$59/                         { POP  DX, CX             }
  69.   $FA/                             { CLI                     }
  70.   $CB ) ;                          { RETF          jmp far p }
  71.  
  72.  
  73. Function Control_Pressed : Boolean ;
  74.  
  75. Procedure EOI ;
  76. { end of interrupt to 8259 }
  77.  
  78. Function ReadScanCode : Byte ;
  79. { read keyboard }
  80.  
  81. Procedure ResetKeyboard ;
  82. { prepare For next key }
  83.  
  84. Procedure StoreKey( Scan, Key : Byte );
  85. { put key in buffer For INT 16 }
  86.  
  87.  
  88. Implementation
  89.  
  90. Uses
  91.   Crt ;  { Sound, NoSound }
  92.  
  93. Type
  94.   Address = Record                  { used in Pointer manipulation }
  95.     Offset : Word ;
  96.     Segment : Word ;
  97.   end ;
  98. Const
  99.   BiosDataSegment = $40 ;
  100.  
  101. Var
  102.   KeyState       : Word Absolute BiosDataSegment:$0017 ;
  103.   KeyBufferHead  : Word Absolute BiosDataSegment:$001A ;
  104.   KeyBufferTail  : Word Absolute BiosDataSegment:$001C ;
  105.   KeyBufferStart : Word Absolute BiosDataSegment:$0080 ;
  106.   KeyBufferend   : Word Absolute BiosDataSegment:$0082 ;
  107.  
  108.  
  109. Function Control_Pressed : Boolean ;
  110. begin
  111.   Control_Pressed := ( KeyState and  4 ) = 4 ;
  112. end;
  113.  
  114. Procedure EOI ;
  115. { end of interrupt to 8259 interrupt controller }
  116. begin
  117.   CLI ;
  118.   Port[$20] := $20 ;
  119. end ;
  120.  
  121. Function ReadScanCode : Byte ;
  122. begin
  123.   ReadScanCode := Port[$60] ;
  124. end ;
  125.  
  126. Procedure ResetKeyboard ;
  127. { prepare For next key }
  128. Var
  129.   N : Byte ;
  130. begin
  131.   N := Port[$61] ;
  132.   Port[$61] := ( N or $80 ) ;
  133.   Port[$61] := N ;
  134. end ;
  135.  
  136. Procedure StoreKey( Scan, Key : Byte ) ;
  137. Var
  138. { put key in buffer that INT 16 reads }
  139.   P : ^Word ;
  140.   N : Word ;
  141. begin
  142.   address(P).segment := BiosDataSegment ;
  143.   N := KeyBufferTail ;
  144.   address(P).offset := N ;
  145.   Inc( N, 2 ) ;                      { advance Pointer two Bytes }
  146.   If( N = KeyBufferend ) then        { end of the circular buffer }
  147.      N := KeyBufferStart ;
  148.   If( N = KeyBufferHead ) then       { buffer full }
  149.   begin
  150.     EOI ;               { EOI must be done before Exit            }
  151.     Sound( 2200 ) ;     {    but before anything that takes a lot }
  152.     Delay( 80 ) ;       {     of time and can be interrupted      }
  153.     NoSound ;
  154.   end
  155.   Else
  156.   begin          { high Byte is scan code, low is ASCII }
  157.     P^ := Scan * $100 + Key ;       { store key in circular buffer }
  158.     KeyBufferTail := N ;            { advance tail Pointer }
  159.     EOI ;
  160.   end ;
  161. end ;
  162.  
  163. end.
  164.  
  165.  
  166.  
  167.  
  168. Unit POLL ;         { polled keyboard handler }
  169.                     { does not support F11 or F12 keys } Interface
  170.  
  171. Const
  172.   EscKey = 1 ;    { key codes }
  173.   aKey = 30 ;
  174.   sKey = 31 ;
  175.   endKey = 79 ;
  176.   DownKey = 80 ;
  177.  
  178. Var
  179.   KeyTable : Array[ 1..127 ] of Boolean ;
  180.  
  181. { KeyTable[ x ] is True when key x is pressed and stays True Until key
  182.   x is released }
  183.  
  184.  
  185. Implementation
  186.  
  187. Uses
  188.   Dos, KeyIntr ;  { keyboard interrupt support }
  189.  
  190. Var
  191.   OldInt09 : Pointer ;
  192.   ExitSave : Pointer ;
  193.  
  194. Procedure RestoreInt09 ; Far;
  195. begin
  196.   ExitProc := ExitSave ;
  197.   SetIntVec( $09, OldInt09 ) ;
  198. end ;
  199.  
  200. Procedure NewInt09 ; interrupt ; Far;
  201. Var
  202.   ScanCode : Byte ;
  203.   KeyCode : Byte ;
  204. begin
  205.   STI ;
  206.   ScanCode := ReadScanCode ;
  207.   KeyCode := ScanCode and $7F ;        { strip make/break bit }
  208.   KeyTable[ KeyCode ] := ( ScanCode and $80 ) = 0 ;
  209.   ResetKeyboard ;
  210.   EOI ;
  211. end ;
  212.  
  213. Var
  214.   N : Byte ;
  215.  
  216. begin
  217.   ExitSave := ExitProc ;
  218.   ExitProc := addr( RestoreInt09 ) ;
  219.  
  220.   For N := 1 to 127 do   { no key pressed }
  221.     KeyTable[ N ] := False ;
  222.  
  223.   GetIntVec( $09, OldInt09 ) ;
  224.   SetIntVec( $09, addr( NewInt09 ) ) ;
  225. end.
  226.